package xyy.d3erpapi.controller;

import com.alibaba.fastjson.JSON;
import lombok.extern.slf4j.Slf4j;
import okhttp3.internal.http2.ErrorCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.*;
import org.springframework.http.ResponseEntity;

import xyy.d3erpapi.enums.HttpErrorCode;
import xyy.d3erpapi.enums.TaskEnum;
import xyy.d3erpapi.pojo.d3po.CallbackResponse;
import xyy.d3erpapi.pojo.d3po.InventoryUpdateRequest;

import xyy.d3erpapi.pojo.d3po.LogisticsRequestDto;
import xyy.d3erpapi.pojo.poppo.PopErpSkuStockV2Dto;
import xyy.d3erpapi.pojo.poppo.SellerOrderDeliverInfoDto;
import xyy.d3erpapi.utils.JsonUtils;
import xyy.d3erpapi.service.D3Service;
import xyy.d3erpapi.service.PopService;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
@RestController
@RequestMapping("/api")
public class ApiController {
    @Autowired
   private D3Service d3Service;
    @Autowired
    private PopService popService;

    private static final int MAX_RETRY_COUNT = 3;
    private AtomicInteger retryCount = new AtomicInteger(0);
    // 存储已处理请求的标志
    private static final ConcurrentHashMap<String, Boolean> processedRequests = new ConcurrentHashMap<>();

    @PostMapping("/inventory")
    public ResponseEntity<CallbackResponse> updateInventory(@RequestParam String appKey,
                                                            @RequestParam String method,
                                                            @RequestParam String timestamp,
                                                            @RequestParam String sign,
                                                            @RequestParam String tag,
                                                            @RequestParam String reqId,
                                                            @RequestBody String request) {

        log.info("请求数据: {}", request.toString());
        log.info("URL参数: appKey={}, method={}, timestamp={}, sign={}, tag={}, reqId={}",
                appKey, method, timestamp, sign, tag, reqId);
        // 验证签名
        Map<String, String> publicParams = new HashMap<String, String>();
        publicParams.put("appKey", appKey);
        publicParams.put("method",method);
        publicParams.put("timestamp",timestamp);
        publicParams.put("reqId", reqId);
        publicParams.put("tag",tag);


        if (!d3Service.validateSignature( publicParams, request,sign)) {
            return ResponseEntity.status(403)
                    .body(new CallbackResponse("推送发⽣了错误", "E10001", false));
        }

        InventoryUpdateRequest inventoryUpdateRequest = JsonUtils.convertJsonToInventoryUpdateRequest(request);
        // 异步处理库存同步逻辑
        CompletableFuture<List<PopErpSkuStockV2Dto>> futureDtos = d3Service.processInventoryUpdate(inventoryUpdateRequest);

        // 这里不等待 futureDtos 的结果以确保快速返回响应
        futureDtos.thenAccept(popService::syncProductStockToPop);

        // 需要3秒内返回响应
        CallbackResponse successResponse = new CallbackResponse("200", true);



        log.info("库存接收完成 响应数据: {}", successResponse.toString());
        return ResponseEntity.ok(successResponse);
    }



// 接收点3物流数据的接口
@PostMapping("/delivery")
public ResponseEntity<CallbackResponse> receiveDelivery(@RequestParam String appKey,
                                                        @RequestParam String method,
                                                        @RequestParam String timestamp,
                                                        @RequestParam String sign,
                                                        @RequestParam String tag,
                                                        @RequestParam String reqId,
                                                        @RequestBody String request) {

    log.info("请求数据: {}", request.toString());
    log.info("URL参数: appKey={}, method={}, timestamp={}, sign={}, tag={}, reqId={}",
            appKey, method, timestamp, sign, tag, reqId);

    // 验证签名
    Map<String, String> publicParams = new HashMap<>();
    publicParams.put("appKey", appKey);
    publicParams.put("method", method);
    publicParams.put("timestamp", timestamp);
    publicParams.put("reqId", reqId);
    publicParams.put("tag", tag);

    if (!d3Service.validateSignature(publicParams, request, sign)) {
        return ResponseEntity.status(HttpStatus.FORBIDDEN)
                .body(new CallbackResponse("推送发⽣了错误,sign校验未通过", "E10001", false));
    }

    LogisticsRequestDto logisticsRequestDto;
    //解析请求
    try {
        // 使用FastJSON将请求数据解析为LogisticsRequestDto对象
        logisticsRequestDto = JSON.parseObject(request, LogisticsRequestDto.class);
    } catch (Exception e) {
        log.error("解析物流请求数据失败", e);
        CallbackResponse parseFailureResponse = new CallbackResponse("解析物流请求数据失败", "E10004", false);
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                .body(parseFailureResponse);
    }
    //调用物流筛选接口，通过返回的订单号集合和点三物流接口的返回值做比对

    List<String> filteredOrderNumbers =popService.queryData(TaskEnum.ORDER_DELIVERY_WMS.getTaskId());

    // 假设点三物流接口返回的订单号集合为 logisticsRequestDto.getrefOid（这里需要根据实际情况获取）
    List<String> logisticsOrderNumbers = new ArrayList<>();
    for (LogisticsRequestDto.Content content : logisticsRequestDto.getContent()) {
        String refOid = content.getRefOid();
        if (refOid!= null) {
            logisticsOrderNumbers.add(refOid);
        }
    }



    //比对一致，上报物流，并返回响应成功
    boolean isMatched = false;
    if (filteredOrderNumbers!= null &&!filteredOrderNumbers.isEmpty()) {
        for (String orderNumber : logisticsOrderNumbers) {
            if (filteredOrderNumbers.contains(orderNumber)) {
                isMatched = true;
                break;
            }
        }
    }

    if (isMatched) {
        // 上报物流并返回响应成功
        log.info("重试请求,该订单直接上报物流数据：{}",logisticsRequestDto.getContent().toString());
        return handleWithoutOutboundCheck(logisticsRequestDto);

    } else {
        // 检查该请求是否已经处理过出库上报验证
        String requestKey = generateRequestKey(request);
        if (processedRequests.containsKey(requestKey)) {
            // 直接进行后续物流上报逻辑，跳过出库上报验证
            log.info("该订单跳过出库上报验证,直接上报物流数据：{}",logisticsRequestDto.getContent().toString());
            return handleWithoutOutboundCheck(logisticsRequestDto);
        }

        // 继续原有的逻辑
        // 调用syncOrderDeliveryDetails方法，并将其执行结果包装在一个CompletableFuture中
        CompletableFuture<ResponseEntity<CallbackResponse>> syncResultFuture = CompletableFuture.supplyAsync(() -> {
            boolean syncResult = popService.syncOrderDeliveryDetails();
            if (syncResult) {
                // 进行后续物流上报相关操作
                // 异步处理物流同步逻辑
                CompletableFuture<List<SellerOrderDeliverInfoDto>> futureDtos = d3Service.convertToOrderDeliverInfo(logisticsRequestDto);
                // 这里不等待futureDtos的结果以确保快速返回响应
                futureDtos.thenAccept(popService::syncDeliverInfo);
                // 使用handle方法处理异步任务的完成和异常情况
                CompletableFuture<ResponseEntity<CallbackResponse>> finalResultFuture = futureDtos.handle((result, ex) -> {
                    if (ex!= null) {
                        // 记录异常信息
                        log.error("物流同步信息上报失败", ex);
                        // 如果是可重试的错误，进行重试
                        if (shouldRetry()) {
                            retryCount.incrementAndGet();
                            return retrySync();
                        } else {
                            // 根据业务需求，返回一个表示失败的响应给调用者
                            CallbackResponse failureResponse = new CallbackResponse("物流同步信息上报失败", "E10002", false);
                            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                                    .body(failureResponse);
                        }
                    } else {
                        // 这里假设同步操作成功后需要返回一个特定的成功响应
                        // 你可以根据实际业务需求调整这个成功响应的内容
                        CallbackResponse successResponse = new CallbackResponse("物流同步信息上报成功", "E10006", true);
                        return ResponseEntity.ok(successResponse);
                    }
                });

                // 等待finalResultFuture完成并获取最终结果
                try {
                    ResponseEntity<CallbackResponse> finalResult = finalResultFuture.get();
                    return finalResult;
                } catch (Exception e) {
                    log.error("获取异步处理物流同步逻辑的最终结果时发生异常", e);
                    CallbackResponse errorResponse = new CallbackResponse("获取异步处理物流同步逻辑结果失败", "E10007", false);
                    return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                            .body(errorResponse);
                }
            } else {
                // 返回失败响应
                CallbackResponse failureResponse = new CallbackResponse("syncOrderDeliveryDetails执行失败", "E10003", false);
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                        .body(failureResponse);
            }
        });

        // 等待syncResultFuture完成并获取最终结果
        try {
            ResponseEntity<CallbackResponse> finalResult = syncResultFuture.get();
            // 将该请求标记为已处理出库上报验证
            processedRequests.put(requestKey, true);
            return finalResult;
        } catch (Exception e) {
            log.error("获取syncOrderDeliveryDetails方法处理结果的最终结果时发生异常", e);
            CallbackResponse errorResponse = new CallbackResponse("获取syncOrderDeliveryDetails方法结果失败", "E10008", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(errorResponse);
        }
    }
}

    private boolean shouldRetry() {
        return retryCount.get() < MAX_RETRY_COUNT;
    }

    private ResponseEntity<CallbackResponse> retrySync() {
        try {
            return receiveDelivery(null, null, null, null, null, null, null);
        } catch (Exception e) {
            log.error("重试失败", e);
            CallbackResponse failureResponse = new CallbackResponse("重试失败", "E10009", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(failureResponse);
        }
    }

    private ResponseEntity<CallbackResponse> handleWithoutOutboundCheck(LogisticsRequestDto logisticsRequestDto) {
        // 直接进行后续物流上报相关操作，无需再次进行出库上报验证
        CompletableFuture<List<SellerOrderDeliverInfoDto>> futureDtos = d3Service.convertToOrderDeliverInfo(logisticsRequestDto);
        futureDtos.thenAccept(popService::syncDeliverInfo);
        CompletableFuture<ResponseEntity<CallbackResponse>> finalResultFuture = futureDtos.handle((result, ex) -> {
            if (ex!= null) {
                log.error("物流同步信息上报失败", ex);
                CallbackResponse failureResponse = new CallbackResponse("物流同步信息上报失败", "E10002", false);
                return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                        .body(failureResponse);
            } else {
                CallbackResponse successResponse = new CallbackResponse("物流同步信息上报成功", "E10006", true);
                return ResponseEntity.ok(successResponse);
            }
        });
        try {
            return finalResultFuture.get();
        } catch (Exception e) {
            log.error("获取异步处理物流同步逻辑的最终结果时发生异常", e);
            CallbackResponse errorResponse = new CallbackResponse("获取异步处理物流同步逻辑结果失败", "E10007", false);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(errorResponse);
        }
    }

    private String generateRequestKey(String request) {
        // 根据请求内容生成一个唯一的键，可以根据实际情况调整生成方式
        return request.hashCode() + "";
    }






}